- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 448
Add support for date range picker on Android #956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add support for date range picker on Android #956
Conversation
This implementation models how the Material date picker was implemented. However, the range picker returns two values and accepts two values for the start and end of the range.
2001f26    to
    079237c      
    Compare
  
    Since this is a new module, I think we should only support the imperative API the same way we encourage developers to use the imperative API for the date and time pickers.
079237c    to
    7d1c6e7      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Left some comments for improvement :) 👍
|  | ||
| class MaterialRangePickerModule(reactContext: ReactApplicationContext): NativeModuleMaterialRangePickerSpec(reactContext) { | ||
| companion object { | ||
| const val NAME = "RNCMaterialRangePicker" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not mistaken, NativeModuleMaterialRangePickerSpec generated by codegen already should contain the name, and so specifying it here should not be needed. also override fun getName should be in the generated code.
if not, it's fine
| val activity = currentActivity as FragmentActivity? | ||
| if (activity == null) { | ||
| promise.reject( | ||
| RNConstants.ERROR_NO_ACTIVITY, | ||
| "Tried to open a MaterialRangePicker dialog while not attached to an Activity" | ||
| ) | ||
| return | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| val activity = currentActivity as FragmentActivity? | |
| if (activity == null) { | |
| promise.reject( | |
| RNConstants.ERROR_NO_ACTIVITY, | |
| "Tried to open a MaterialRangePicker dialog while not attached to an Activity" | |
| ) | |
| return | |
| } | |
| val activity = currentActivity as FragmentActivity? ?: run { | |
| return promise.reject( | |
| RNConstants.ERROR_NO_ACTIVITY, | |
| "Tried to open a MaterialRangePicker dialog while not attached to an Activity" | |
| ) | |
| } | 
this is more kotlin-style; just a suggestion. I'm not sure how it'll work with the cast though.
|  | ||
| if (args.containsKey(RNConstants.ARG_START_TIMESTAMP)) { | ||
| // override "value" so we can use the same constructor from RNDate | ||
| args.putLong(RNConstants.ARG_VALUE, args.getLong((RNConstants.ARG_START_TIMESTAMP))) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than mutating args in order to use some constructor of RNDate, I'd add another constructor to RNDate which accepts Long value
| val title = args.getString(RNConstants.ARG_TITLE) | ||
| if (!title.isNullOrEmpty()) { | ||
| builder.setTitleText(args.getString(RNConstants.ARG_TITLE)) | ||
| } | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| val title = args.getString(RNConstants.ARG_TITLE) | |
| if (!title.isNullOrEmpty()) { | |
| builder.setTitleText(args.getString(RNConstants.ARG_TITLE)) | |
| } | |
| args.getString(RNConstants.ARG_TITLE)?.let { | |
| builder.setTitleText(it) | |
| } | 
more kotlin-y. You can use this pattern more across this file pls, e.g in setButtons.
| val result = WritableNativeMap() | ||
|  | ||
| result.putString("action", RNConstants.ACTION_RANGE_SET) | ||
| result.putDouble("startTimestamp", getStartTimestamp(selection)) | ||
| result.putDouble("endTimestamp", getEndTimestamp(selection)) | ||
| result.putDouble( | ||
| "utcOffset", | ||
| getStartTimestamp(selection) / 1000 / 60 | ||
| ) | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| val result = WritableNativeMap() | |
| result.putString("action", RNConstants.ACTION_RANGE_SET) | |
| result.putDouble("startTimestamp", getStartTimestamp(selection)) | |
| result.putDouble("endTimestamp", getEndTimestamp(selection)) | |
| result.putDouble( | |
| "utcOffset", | |
| getStartTimestamp(selection) / 1000 / 60 | |
| ) | |
| val result = WritableNativeMap().apply { | |
| putString("action", RNConstants.ACTION_RANGE_SET) | |
| putDouble("startTimestamp", getStartTimestamp(selection)) | |
| putDouble("endTimestamp", getEndTimestamp(selection)) | |
| putDouble( | |
| "utcOffset", | |
| getStartTimestamp(selection) / 1000 / 60 | |
| ) | |
| } | 
more koltin-y. You can use apply in many places throughout this file to save keystrokes
Summary
This adds support for Material 3's date range picker. I've added this as an imperative API similar to how the date and time pickers can be called imperatively on Android. Many of the props the new date Material date picker supports are supported here as well. There are some small differences in the following props:
valueandonChange.valuemust be aRangeobject that looks like{start: Date?, end: Date?}. These are optional and thevalueprop itself is optional. Leaving it undefined will open the picker with a clean slate.onChangereturns astartTimestampandendTimestampin thenativeEventpayload and returns aRangeobject as the second parameter.See the README for a screenshot.
Test Plan
What's required for testing (prerequisites)?
What are the steps to reproduce (after prerequisites)?
Compatibility
Checklist
README.mdexample/App.js)